#pragma once

#include "XiolController.h"
#include <vector>

namespace Xiol
{

class ControllerEnumerationTrigger;

/*
	ControllerManager
	
	The ControllerManager is responsible for detecting Controllers connected to the machine
	and provide access to them. 

	The ControllerManager must be updated at a regular interval by the client code in order 
	for it to refresh the state of the connected controllers.

	It's possible to be notified whenever a controller is connected or disconnect to/from the
	machine. This is done by register a listener to the ControllerManager. Not that the listener
	is not owned by the ControllerManager.
*/
class ControllerManager
{
public:
	ControllerManager();
	virtual ~ControllerManager();

	DWORD			getMaxNumControllers() const					{ return mNumMaxControllers; }
	Controller*		getController( DWORD controllerIndex ) const	{ return mControllers[controllerIndex]; }
	
	void			update();
	
	class Listener
	{
	public:
		virtual void onControllerConnected( ControllerManager* controllerManager, Controller* controller ) {}
		virtual void onControllerDisconnecting( ControllerManager* controllerManager, Controller* controller ) {}
	};
	
	typedef			std::vector<Listener*> Listeners; 
	void			addListener( Listener* listener );
	bool			removeListener( Listener* listener );
	Listeners		getListeners() const { return mListeners; }

private:
	static bool		getControllerCapabilities( DWORD controllerIndex, XINPUT_CAPABILITIES& capabilities );
	Controller*		addController( DWORD controllerIndex, const XINPUT_CAPABILITIES& capabilities );
	void			updateController( DWORD controllerIndex );
	void			deleteController( DWORD controllerIndex );
	void			deleteAllControllers();

	ControllerEnumerationTrigger* mEnumerationTrigger;
#ifndef XINPUT_USE_9_1_0
	static const DWORD mNumMaxControllers = XUSER_MAX_COUNT;
#else
	static const DWORD mNumMaxControllers = 4;
#endif
	Controller*		mControllers[mNumMaxControllers];

	Listeners		mListeners;
};

}
